package BLL;

import java.util.*;

import DTO.*;
import DAL.*;
import GUI.*;
import javax.swing.JFrame;

/**
 * Classe responsável pelo gerenciamento dos registros de jogos e as ações tomadas
 * em menus do jogo.
 *
 * @author (R. Soares)
 * @version (1.0 - 24.05.2010)
 */
public class GerenciadorJogo
{
    // Variáveis de Instancia ------------------------------------------ *
    private ExecutorJogo executor;
    private String nomeJogoAtivo;
    private String nomePartidaAtiva;

    // Contrutores  ------------------------------------------------------ *
    /**
     * Construtor da Classe GerenciadorJogo
     */
    public GerenciadorJogo()
    {
        nomeJogoAtivo = null;
        nomePartidaAtiva = null;
    }

    // Método ------------------------------------------------------- *

    /**
     * Método principal de execucao do sistema. Abre o menu e processa as opções
     * selecionadas (Novo jogo, Abrir jogo, Salvar Jogo e Sair). Caso seja feita a opção
     * por sair, encerra o sistema.
     */
    public void executarSistema(int opcao)
    {
        
        while( opcao != 10)
        {

            // opcao 1 - Novo Jogo
            if(opcao == 1)
                iniciarNovoJogo(0);

            // opcao 2 - Renovar Jogo
            if(opcao == 2)
                iniciarNovoJogo(1);

            // opcao 3 - Abrir Menu de Lista de Jogos sem jogo ativo
            if(opcao == 3)
                opcao = executarLista();

            // opcao 3 - Abrir Menu de Lista de Jogos com jogo ativo
            if(opcao == 4)
                opcao = executarLista();

            // opcao 5 - Abrir Jogo Salvo
            if(opcao == 5)
                    abrirJogo();

            // opcao 6 - Salvar Jogo
            if(opcao == 6)
                    salvarJogo();

            // opcao 7 - Apagar jogo
            if(opcao == 7)
                apagarJogo();

             // opcao 8 - Retomar Jogo
            if(opcao == 8)
                executor. executarJogo(3);

            // opcao 9 - saida de tela e retorno ao menu, não necessita teste
        }

        System.exit(0);
    }


    /**
     * Método que abre a lista de jogos salvos para seu gerenciamento. Retorna
     * identificador da ação tomada para o registro.
     *
     * @return   int : Opcao selecionada
     */
    private int executarLista()
    {
        int opcao = 0;

        // Cria uma nova área de lista de Jogos
        ListaGUI listaJogo = new ListaGUI( obterListaJogos() );

        // Apresenta a tela de menu
        listaJogo.showWindow();

        // Consulta continua das opções selecionadas.
        while ( opcao == 0 )
        {
            opcao = listaJogo.getOpcao();

            // Caso tenha sido solicitado abrir ou apagar um jogo,
            //  obtem o nome do jogo
            if(opcao == 5 || opcao == 7){
                nomeJogoAtivo = listaJogo.getJogoSelecionado();
                nomePartidaAtiva = listaJogo.getPartidaSelecionada();
            }
        }

        //  Fecha e deleta a área de lista de Jogo
        listaJogo.dispose();

        return opcao;
    }


    /**
     * Método que retorna lista de nomes dos jogos salvos
     *
     * @return   ArrayList : Lista de nome dos jogos salvos
     */
    private ArrayList obterListaJogos()
    {
        ArrayList listaNomes = null;
        HashMap listaJogos = new JogoDAL().getListaTodos();

        if ( listaJogos != null)
        {
            listaNomes = new ArrayList();

            Iterator it = listaJogos.keySet().iterator();

            while( it.hasNext() )
            {
                listaNomes.add( (String) it.next() );
            }
        }

        return listaNomes;
    }

    /**
     * Método que inicia um novo jogo.
     *
     * @param  int - acao : Identificador da ação tomada ao iniciar um novo jogo
     *                                  0 - Iniciar Jogo  ;   1 - Limpar tela e iniciar jogo
     */
    public void iniciarNovoJogo(int acao)
    {
        // Gera um novo jogo com o identificador atribuído
        JogoDTO jogo = new GeradorJogo().gerarNovoJogo(nomeJogoAtivo, nomePartidaAtiva);

        // Cria um novo executor de jogos
        executor = new ExecutorJogo(jogo);

        // executa o jogo, se a execução for interrompida retorna o identificador do
        // jogo ativo.
        nomeJogoAtivo = executor. executarJogo(acao);
    }

   /**
     * Método que salva o jogo ativo.
     */
    private void salvarJogo()
    {
        JogoDTO jogo = executor.retornarJogoAtivo();

        new JogoDAL().gravarJogo(jogo);
    }

   /**
     * Método que apaga o jogo ativo.
     */
    private void apagarJogo()
    {
        new JogoDAL().removeJogo(nomeJogoAtivo);
    }

   /**
     * Método que abre um jogo.
     */
    private void abrirJogo()
    {
        // Obtem o jogo salvo
        JogoDTO jogo = new JogoDAL().selecionarPorID(nomeJogoAtivo);

        jogo = new GeradorJogo().gerarJogoSalvo(jogo);

        if(executor == null)
        {
            executor = new ExecutorJogo(jogo);
            nomeJogoAtivo = executor. executarJogo(0);
        }
        else
        {
            executor = new ExecutorJogo(jogo);
            nomeJogoAtivo = executor. executarJogo(1);
        }
    }
    
    public void iniciar(){
        TelaInicial ti = new TelaInicial();
        JFrame jf = new JFrame();
        jf.setSize(588, 555);
        jf.setContentPane(ti);
        jf.show();
    }
}
